package com.gxy.learn.xdocreport;


import fr.opensagres.xdocreport.converter.ConverterTypeTo;
import fr.opensagres.xdocreport.converter.ConverterTypeVia;
import fr.opensagres.xdocreport.converter.Options;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.FileImageProvider;
import fr.opensagres.xdocreport.document.images.IImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * docx -> pdf
 * https://gitee.com/wahnn/xdocreport.samples/tree/master/samples/fr.opensagres.xdocreport.samples.docx.converters
 * template -> docx
 * https://gitee.com/wahnn/xdocreport.samples/tree/master/samples/fr.opensagres.xdocreport.samples.docxandfreemarker/src/fr/opensagres/xdocreport/samples/docxandfreemarker
 */
@Slf4j
public class XdocreportUtils {

    public static void main(String[] args) {

        Map<String, Object> param = new HashMap<>();
        param.put("user.username", "小明不怕不怕啦");
        param.put("user.hobby", "爱玩dota");
        param.put("name", "sssssssssssssssssssssss");
        String rootPath = XdocreportUtils.class.getClassLoader().getResource("").getPath();
        String filePath = String.format("%stemplates/xdocxtemplate.docx", rootPath);
        Map<String, IImageProvider> imgMap = new HashMap<>();
        IImageProvider logo = new FileImageProvider(new File(String.format("%simg/2021122211591833953227008.png", rootPath)), true);
        logo.setSize(500f, 500f);
        imgMap.put("logo", logo);
        IImageProvider pic = new FileImageProvider(new File(String.format("%simg/suoluePic.png", rootPath)), true);
        pic.setSize(200f, 200f);
        imgMap.put("pic", pic);
        exportDocx(param, imgMap, new File(filePath), "C:\\Users\\Administrator\\Desktop\\DocxProjectWithFreemarker_Out.docx");


        exportPdf(param, imgMap, new File(filePath), "C:\\Users\\Administrator\\Desktop\\DocxProjectWithFreemarker_Out.pdf");
        pdfToImg(new File("C:\\Users\\Administrator\\Desktop\\DocxProjectWithFreemarker_Out.pdf"), "C:\\Users\\Administrator\\Desktop");
    }


    public static void exportDocx(Map<String, Object> param, Map<String, IImageProvider> imgMap, File templateFIle, String outPath) {
        try {
            InputStream in = new FileInputStream(templateFIle);
            //载入模板
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
            IContext context = report.createContext();
            //设置要替换的值
            if (MapUtils.isNotEmpty(param)) {
                for (Map.Entry<String, Object> entry : param.entrySet()) {
                    context.put(entry.getKey(), entry.getValue());
                }
            }
            FieldsMetadata metadata = report.createFieldsMetadata();
            report.setFieldsMetadata(metadata);
            //替换图片
            if (MapUtils.isNotEmpty(imgMap)) {
                for (Map.Entry<String, IImageProvider> entry : imgMap.entrySet()) {
                    context.put(entry.getKey(), entry.getValue());
                    metadata.addFieldAsImage(entry.getKey());
                }
            }
            report.setFieldsMetadata(metadata);

            OutputStream out = new FileOutputStream(new File(outPath));
            report.process(context, out);
            out.close();
        } catch (IOException e) {
            log.error("导出docx文件出现异常！", e);
        } catch (XDocReportException e) {
            log.error("导出docx文件出现异常！", e);
        }
    }

    public static void exportPdf(Map<String, Object> param, Map<String, IImageProvider> imgMap, File templateFIle, String outPath) {
        try {
            InputStream in = new FileInputStream(templateFIle);
            //载入模板
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
            IContext context = report.createContext();
            //设置要替换的值
            if (MapUtils.isNotEmpty(param)) {
                for (Map.Entry<String, Object> entry : param.entrySet()) {
                    context.put(entry.getKey(), entry.getValue());
                }
            }
            FieldsMetadata metadata = report.createFieldsMetadata();
            report.setFieldsMetadata(metadata);
            //替换图片
            if (MapUtils.isNotEmpty(imgMap)) {
                for (Map.Entry<String, IImageProvider> entry : imgMap.entrySet()) {
                    context.put(entry.getKey(), entry.getValue());
                    metadata.addFieldAsImage(entry.getKey());
                }
            }
            report.setFieldsMetadata(metadata);
            OutputStream out = new FileOutputStream(new File(outPath));
            Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF);
            report.convert(context, options, out);
            out.close();
        } catch (IOException e) {
            log.error("导出pdf文件出现异常！", e);
        } catch (XDocReportException e) {
            log.error("导出pdf文件出现异常！", e);
        }
    }

    public static void pdfToImg(File pdfFile, String outPath) {

        PDDocument doc = null;
        try {
            doc = PDDocument.load(pdfFile);
            PDFRenderer render = new PDFRenderer(doc);
            int count = doc.getNumberOfPages();
            for (int i = 0; i < count; i++) {
                // 设置图片的分辨率
                BufferedImage image = render.renderImageWithDPI(i, 296);
                // 如果是PNG图片想要背景透明的话使用下面这个
                // BufferedImage image = render.renderImageWithDPI(i, 296,
                // ImageType.ARGB);
                ImageIO.write(image, "PNG", new File(outPath + File.separator + i + ".png"));

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (doc != null) {
                    doc.close();
                }
            } catch (IOException e) {
                log.error("err", e);
            }
        }
    }

    /**
     * pdf转图片
     *
     * @param path
     * @param dest
     * @throws IOException
     */
    public static void readPdfToImage(String path, String dest) throws IOException {
        PDDocument doc = null;
        try {
            doc = PDDocument.load(new File(path));
            PDFRenderer render = new PDFRenderer(doc);
            int count = doc.getNumberOfPages();
            for (int i = 0; i < count; i++) {
                // 设置图片的分辨率
                BufferedImage image = render.renderImageWithDPI(i, 296);
                // 如果是PNG图片想要背景透明的话使用下面这个
                // BufferedImage image = render.renderImageWithDPI(i, 296,
                // ImageType.ARGB);
                ImageIO.write(image, "PNG", new File(dest + File.separator + i + ".png"));

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (doc != null) {
                doc.close();
            }
        }
    }
}

